#ifndef TERMSTRUCTURE_SWAP_HPP
#define TERMSTRUCTURE_SWAP_HPP

#include "timeSequence.hpp"
#include "timeSequenceHolder.hpp"
#include "ForwardRateSequence.hpp"

namespace TermStructure
{
    //! Swap Contract
    /*! Define a swap contract. The enter index is when the swap is entered, The first payment shoudl occur at enterindex + 1. The end index is the time of the last payment.
     */
	template<typename T, typename TSize = long>
	class Swap : public TimeSequenceHolder<T,TSize>
	{
	public:
        //! Initiate a swap
        /*! \param times TimeSequence of the swap
            \param swapEndeIndex the time idnex of the last payment
            \param swapEnterIndex the time index of the first payment - 1
         */
		Swap(TimeSequence<T,TSize> &times, TSize swapEndIndex = 0, TSize swapEnterIndex = 0) : SwapEndIndex(swapEndIndex), SwapEnterIndex(swapEnterIndex)
		{
			this->_timeSequence = &times;
			this->Notional = 1;
		}
        //! Strike Rate of the Swap
		mutable T Strike;
        //! The time index that the swap starts, the first payment is this time +1
		TSize SwapEnterIndex;
        //! the time index that the swap ends.
		TSize SwapEndIndex;
        //! Notional amount, defaults to 1.
		T Notional;
        //! Price a swap based on the given forward rate sequence. PricingPoint is the time index that the swap is priced.
		T Price(const ForwardRateSequence<T,TSize> &forwardRate, TSize pricingPoint = 0) const
		{
			T result = 0;
			forwardRate.EstablishDiscountFactors();
			for(TSize i = SwapEnterIndex + 1; i <= SwapEndIndex; i++)
			{
				result += forwardRate.DiscountFactorAt(i, pricingPoint) * (forwardRate[i] - Strike)* this->_timeSequence->TimeDifference(i)*Notional;
			}
			return result;
		}
		
	};

}

#endif